package com.beiding.controller.user;

import com.beiding.exception.RegisterException;
import com.beiding.pojo.auth.User;
import com.beiding.service.email.EmailService;
import com.beiding.service.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;
import java.security.Principal;

@Controller
@RequestMapping("/user")
public class UserController {


    private UserService userService;

    private EmailService emailService;

    @Autowired
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    @Secured("ROLE_USER")
    String index(Principal principal, Model model) {

        User user = userService.getUser(principal.getName());

        model.addAttribute("username", principal.getName());

        model.addAttribute("email", user.getIncompleteEmail());

        return "user/index";
    }


    //注册
    @GetMapping("/register")
    String register(Model model, HttpSession session) {

        if (!model.containsAttribute("user"))
            model.addAttribute("user", new User());


        //登录拦截的地址.用户在注册完成后跳转
        String rUri;

        try {
            rUri = ((DefaultSavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).getRequestURI();
        } catch (Exception e) {
            rUri = "/";
        }

        model.addAttribute("rUri", rUri);

        return "user/register";
    }


    @PostMapping("/register")
    String register(@Validated User user, Errors errors, String code, Model model, HttpSession session) {

        model.addAttribute("user", user);

        //如果有错误就返回前端,使用Spring表单绑定对错误进行渲染
        if (errors.hasErrors())
            return "user/register";


        try {
            emailService.checkCode(user.getEmail(), code);

            //保存用户的时候还会进行深层次的校验,如果校验出现错误将会交给前端进行处理
            userService.save(user);

            //将验证码失效
            emailService.invalidateCode(code);
        } catch (RegisterException e) {

            //将异常捕获,封装进Model
            model.addAttribute(e.getField(), e.getMessage());
            return "user/register";
        }


        //登录拦截前的地址
        String rUri;
        try {
            rUri = ((DefaultSavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).getRequestURI();
        } catch (Exception e) {
            rUri = "/";
        }

        model.addAttribute("rUri", rUri);


        //重定向到登录界面
        return "user/registerToLogin";
    }

    @GetMapping("/login")
    String login(Model model, @RequestParam(required = false) String error) {

        //如果用户名密码错误重定向这里,则提示
        if (error != null) {
            model.addAttribute("msg", "用户名或密码错误");
        }

        return "user/login";
    }


    /*
        找回密码要求用户输入找回密码的账户名.在用户发起post请求后会响应提示邮箱
     */
    @GetMapping("/retrieve-password")
    String retrievePassword(Model model, HttpSession session) {

        //登录拦截前的地址
        String rUri;
        try {
            rUri = ((DefaultSavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).getRequestURI();
        } catch (Exception e) {
            rUri = "/";
        }

        if (rUri.equals("")) {
            rUri = "/";
        }

        model.addAttribute("rUri", rUri);

        return "user/retrievePassword";
    }

    //找回新密码
    @GetMapping("/retrieve-password/new")
    String retrievePasswordNew(String token, Model model) {

        //找回密码的邮件是一个以令牌作文请求参数的连接,通过这个令牌可以找到对应的用户.
        String username = emailService.getUsernameByToken(token);


        //密文有效的标志是能否通过密文找到对应的用户名
        if (username != null) {
            model.addAttribute("token", token);
            model.addAttribute("username", username);
        } else {

            //相反如果密文无效
            model.addAttribute("error", "无效的令牌或已失效");
        }

        //使用c标签库
        return "user/retrievePassword";
    }


}
